package org.jeecg.modules.activiti.service.Impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.ibatis.annotations.Param;
import org.jeecg.common.util.EmptyUtil;
import org.jeecg.modules.activiti.entity.ActBusiness;
import org.jeecg.modules.activiti.entity.ActZTask;
import org.jeecg.modules.activiti.mapper.ActZTaskMapper;
import org.jeecg.modules.activiti.service.IActZTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * @Description: 待办任务扩展表
 * @Author: qixin-boot
 * @Date:   2022-02-08
 * @Version: V1.0
 */
@Service
public class ActZTaskServiceImpl extends ServiceImpl<ActZTaskMapper, ActZTask> implements IActZTaskService {

    @Autowired
    private ActZTaskMapper actZTaskMapper;

    @Override
    public void updateState(String id, Integer state, Integer nodeState,String comment) {
        this.baseMapper.updateState(id, state, nodeState, comment);
    }

    /**
     * 流程撤回/收回
     * @param procInstId 流程实例id
     * @param taskId 当前已办任务Id
     * @param actZTaskId 待办任务表Id -- 用来更新已办状态
     * @param isStarter 是否为发起人
     * @param actBusiness 流程业务扩展表
     * @return true 表示成功
     */
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Boolean withdraw(String procInstId, String taskId, String actZTaskId, Boolean isStarter,
                            Integer serial,ActBusiness actBusiness) {

        // 代码逻辑要分发起人撤回 和 审批人收回

        if (isStarter){
            /*
            发人撤回-> 步骤
            1、从历史流程任务表(act_hi_taskinst)获取发起人已办任务信息、历史流程人员表(act_hi_identitylink);
            2、删除流程实例的历史执行记录 -- 根据procInstId来删除
            3、把第一步获取到的已办任务信息保存到 运行时待办任务表(act_ru_task)、运行时参与人表(act_ru_identitylink)
            */

            // 获取下节点待办任务Id 为空的话不能撤回
            String nextTaskId = this.baseMapper.getTaskId(procInstId);
            if (nextTaskId == null){
                return false;
            }

            //根据任务Id获取历史流程任务表信息(act_hi_taskinst) -- 当前发起人任务Id
            Map<String,Object> actHiTaskMap = this.baseMapper.selectHiTaskById(taskId);
            if (actHiTaskMap == null){
                return false;
            }
            //获取已办任务里特征表中的最新的数据:taskId,procInstId
            List<Map<String, Object>> actHiIdentityList = this.baseMapper.selectLastHiIdentity(taskId);

            //根据流程实例Id-删除历史节点表的 保留当前节点记录taskId
            this.baseMapper.delHiTaskByProcInstId(procInstId, taskId);

            //删除历史流程人员表-发起人撤回时(act_hi_identitylink):ProcInstId:节点实例id
            this.baseMapper.delActHiIdentityByProcInstId(procInstId);

            //删除历史意见表-意见(act_hi_comment):procInstId(流程实例id)
            this.baseMapper.delActHiCommentByProcInstId(procInstId);

            //删除运行时流程人员表-节点参与者(act_ru_identitylink):task_id_(待办任务id)
            this.baseMapper.deleteActRuIdentity(nextTaskId);

            //删除运行时流程人员表-节点参与者(act_ru_identitylink):ProcInstId(流程实例id)
            this.baseMapper.delActRuIdentityByProcInstId(procInstId);

            //删除运行时任务节点表-待办任务(act_ru_task)字段:id_(待办任务id)
            this.baseMapper.deleteRuTask(nextTaskId);

            //将查询出来的已办任务(act_hi_taskinst)数据,插入到待办任务表(act_ru_task)
            this.baseMapper.insertActRuTask(actHiTaskMap);

            //将上一个节点已办的任务特征表(act_hi_identitylink),插入到待办的特征表(act_ru_identitylink)
            if(actHiIdentityList != null && actHiIdentityList.size() > 0){
                for (int i = 0; i < actHiIdentityList.size(); i++) {
                    Map<String,Object> actHiIdentityMap = actHiIdentityList.get(i);
                    this.baseMapper.insertActRuIdentity(actHiIdentityMap);
                }
            }

            //获取已办任务里的最新的任务id(再前一个已办任务id)(当前流程实例,同时end_time_不为空,task_id不为空)
            Map<String,Object> actHiActinst = this.baseMapper.selectActHiActinst(taskId);
            String startTime = "1900-01-01";    //开始时间
            if(actHiActinst != null){
                startTime = EmptyUtil.checkNull(actHiActinst.get("START_TIME_"));
            }

            //删除历史节点表(act_hi_actinst)中,字段:procInstId(流程实例id,并且时间大于上一个及诶单任务的所有记录)
            this.baseMapper.deleteActHiActinst(procInstId, startTime);

            //更新历史节点表(act_hi_taskinst)中,字段:task_id_(已办任务id),将结束日期清空,持续时间清空
            this.baseMapper.updateActHiTaskinst(taskId);

            //更新运行时流程执行实例表(act_ru_execution)字段:act_id_为上一节点任务的task_def_key_值
            String taskDefKey = EmptyUtil.checkNull(actHiTaskMap.get("TASK_DEF_KEY_"));
            this.baseMapper.updateActRuExecution(procInstId,taskDefKey);

            // 删除待办任务扩展表历史节点
            this.baseMapper.delActZTasckByProcInstId(serial,procInstId);

            // 更新单据状态、待办任务状态 如果是发起人的话，把状态改为0
            this.baseMapper.updateState(actZTaskId,0,0,"");
            this.baseMapper.updateBusinessState(actBusiness.getTableName(),actBusiness.getTableId(),"0");
        }else{
            /*
            审批人收回-> 步骤
            1、从历史流程任务表(act_hi_taskinst)获取当前节点已办任务信息、历史流程人员表(act_hi_identitylink);
            2、删除当前节点任务的历史执行记录
            3、把第一步获取到的已办任务信息保存到 运行时待办任务表(act_ru_task)、运行时参与人表(act_ru_identitylink)
            */
            // 获取下节点待办任务Id 为空的话不能撤回
            String nextTaskId = this.baseMapper.getTaskId(procInstId);
            if (nextTaskId == null){
                return false;
            }

            //获取已办任务里的最新的任务id(当前流程实例,同时end_time_不为空,task_id不为空) -- 当前已办人任务Id
            Map<String,Object> actHiTaskMap = this.baseMapper.selectLastHiTask(procInstId);

            //获取已办任务里特征表中的最新的数据:taskId,procInstId
            List<Map<String, Object>> actHiIdentityList = this.baseMapper.selectLastHiIdentity(taskId);

            //删除历史任务表任务(act_hi_taskinst)字段:id_(待办任务id)
            this.baseMapper.deleteHiTask(nextTaskId);

            //更新历史任务表已办任务(act_hi_taskinst)字段:id_(已办任务id)::结束时间清空,持续时间清空,删除理由清空
            this.baseMapper.updateActHiTask(taskId);

            //删除历史流程人员表-待办任务(act_hi_identitylink):task_id_(待办任务id)
            this.baseMapper.deleteActHiIdentityByTaskId(nextTaskId);

            //删除历史流程人员表-已办任务(act_hi_identitylink):task_id_(已办任务id),流程实例id
            this.baseMapper.deleteActHiIdentity(taskId,procInstId);

            //删除历史意见表-意见(act_hi_comment):task_id_(已办任务id)
            this.baseMapper.deleteActHiComment(taskId);

            //删除运行时流程人员表-节点参与者(act_ru_identitylink):task_id_(待办任务id)
            this.baseMapper.deleteActRuIdentity(nextTaskId);

            //删除运行时任务节点表-待办任务(act_ru_task)字段:id_(待办任务id)
            this.baseMapper.deleteRuTask(nextTaskId);

            //将查询出来的已办任务(act_hi_taskinst)数据,插入到待办任务表(act_ru_task)
            this.baseMapper.insertActRuTask(actHiTaskMap);

            //将上一个节点已办的任务特征表(act_hi_identitylink),插入到待办的特征表(act_ru_identitylink)
            if(actHiIdentityList != null && actHiIdentityList.size() > 0){
                for (int i = 0; i < actHiIdentityList.size(); i++) {
                    Map<String,Object> actHiIdentityMap = actHiIdentityList.get(i);
                    this.baseMapper.insertActRuIdentity(actHiIdentityMap);
                }
            }

            //获取已办任务里的最新的任务id(再前一个已办任务id)(当前流程实例,同时end_time_不为空,task_id不为空)
            Map<String,Object> actHiActinst = this.baseMapper.selectActHiActinst(taskId);
            String startTime = "1900-01-01";    //开始时间
            if(actHiActinst != null){
                startTime = EmptyUtil.checkNull(actHiActinst.get("START_TIME_"));
            }

            //删除历史节点表(act_hi_actinst)中,字段:proc_inst_id_(流程实例id,并且时间大于上一个及诶单任务的所有记录)
            this.baseMapper.deleteActHiActinst(procInstId, startTime);

            //更新历史节点表(act_hi_taskinst)中,字段:task_id_(已办任务id),将结束日期清空,持续时间清空
            this.baseMapper.updateActHiTaskinst(taskId);

            //更新运行时流程执行实例表(act_ru_execution)字段:act_id_为上一节点任务的task_def_key_值
            String taskDefKey = EmptyUtil.checkNull(actHiTaskMap.get("TASK_DEF_KEY_"));
            this.baseMapper.updateActRuExecution(procInstId,taskDefKey);

            // 删除待办任务扩展表历史节点
            this.baseMapper.delActZTasckByProcInstId(serial,procInstId);

            // 更新单据状态、待办任务状态
            this.baseMapper.updateState(actZTaskId,1,0,"");

        }
        return true;
    }

    @Override
    public void updateActZTaskState(Integer state, String procInstId) {
        this.baseMapper.updateActZTaskState(state, procInstId);
    }

    /**
     * @Description: TODO
     * @author: CYS
     * @date: 2022/3/1 10:35
     * @param tableId:
     * @Return:
     */
    @Override
    public ActZTask getActZTaskByTableId(@Param("tableId") String tableId){
        return  actZTaskMapper.getActZTaskByTableId(tableId);
    }

    @Override
    public void insertActRuExecution(Map<String, Object> actRuExecution) {
        this.baseMapper.insertActRuExecution(actRuExecution);
    }

    @Override
    public void deleteHiTask(String taskId) {
        this.baseMapper.deleteHiTask(taskId);
    }

    @Override
    public void updateActHiProcInstEndtime(String procInstId) {
        this.baseMapper.updateActHiProcInstEndtime(procInstId);
    }

    @Override
    public void delActZTaskByTaskIdProcInstId(String procInstId, String taskId) {
        this.delActZTaskByTaskIdProcInstId(procInstId, taskId);
    }

    @Override
    public String getActHiIdentitylinkById(String procInstId, String taskId) {

        return  this.actZTaskMapper.getActHiIdentitylinkById(procInstId, taskId);
    }
}
